package strauss.flatland.model;

import java.awt.Color;
import java.util.List;
import java.util.Random;
import java.util.Vector;
import java.util.concurrent.Semaphore;

import strauss.flatland.things.IThing;
import strauss.flatland.things.Line;
import strauss.flatland.things.Dot;
import strauss.flatland.things.geometry.Vertex;
import strauss.flatland.things.geometry.GeometricVector;

/**
 * @author Sybrand
 * responsibilities:
 * - tell view to update when model changes
 */
public class FlatLandModel {
	private List<IThing> things;
	private long time=0;
	private Semaphore updated = new Semaphore(1);
	
	public FlatLandModel() {
		// we use a vector, because it's thread safe
		// the model is potentially going to be accessed by numerous
		// threads, so we want to be sure it can hold up
		things = new Vector<IThing>();
		things.add(new Dot(new Vertex(20, 10), new GeometricVector(0.00, -0.25), Color.orange));
		things.add(new Dot(new Vertex(30, 30), new GeometricVector(1.00, 0.00)));
		things.add(new Dot(new Vertex(30, 10), new GeometricVector(1.00, 0.00), Color.red));
		things.add(new Dot(new Vertex(160, 10), new GeometricVector(-1.00, 0.00), Color.green));
		
		things.add(new Dot(new Vertex(60, 10), new GeometricVector(0.25, 0.25), Color.red));
		things.add(new Dot(new Vertex(100, 50), new GeometricVector(-0.25, -0.25), Color.green));
		
		things.add(new Dot(new Vertex(40, 50), new GeometricVector(1.25, 1.25), Color.black));
		things.add(new Dot(new Vertex(50, 80), new GeometricVector(1.25, 1.25)));
		things.add(new Dot(new Vertex(150, 150), new GeometricVector(-0.25, -0.5)));
		
		Random rand = new Random();
		for (int i=0;i<400;++i) {
			double x = Math.abs(rand.nextInt())%140+10;
			double y = Math.abs(rand.nextInt())%140+10;
			double dx = (rand.nextInt()%20)/10.0;
			double dy = (rand.nextInt()%20)/10.0;
			things.add(new Dot(new Vertex(x, y), new GeometricVector(dx, dy)));
		}
		
		things.add(new Line(new Vertex(1, 1), new Vertex(200, 1), new GeometricVector(0, 0)));
		things.add(new Line(new Vertex(1, 1), new Vertex(1, 200), new GeometricVector(0, 0)));
		things.add(new Line(new Vertex(200, 1), new Vertex(200, 200), new GeometricVector(0, 0)));
		things.add(new Line(new Vertex(1, 200), new Vertex(200, 200), new GeometricVector(0, 0)));
	}
	
	public synchronized List<IThing> getThings() {
		return things;
	}

	public void incrementTime() {
		++time;
	}
	
	public Semaphore getSemaphore() {
		return updated;
	}
}
